package com.mask.im.business.handler;

import lombok.extern.log4j.Log4j2;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpInputMessage;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;

/**
 * 解密HTTP输入消息处理器
 * 负责对加密的请求体进行解密处理
 * 
 * @author jian
 */
@Log4j2
public class DecryptHttpInputMessageHandler implements HttpInputMessage {

    private final HttpInputMessage inputMessage;
    private final String charset;
    private final String key;
    private final CryptoService cryptoService;

    public DecryptHttpInputMessageHandler(HttpInputMessage inputMessage, String charset, String key, CryptoService cryptoService) {
        this.inputMessage = inputMessage;
        this.charset = charset;
        this.key = key;
        this.cryptoService = cryptoService;
    }

    @Override
    public InputStream getBody() throws IOException {
        try {
            log.debug("开始解密请求体");
            
            // 读取原始请求体
            InputStream originalBody = inputMessage.getBody();
            String encryptedContent = readInputStream(originalBody, charset);
            
            if (encryptedContent == null || encryptedContent.trim().isEmpty()) {
                log.warn("请求体为空，跳过解密");
                return new ByteArrayInputStream(new byte[0]);
            }
            
            // 解密内容
            byte[] decryptedBytes = cryptoService.decrypt(encryptedContent, key, charset);
            
            log.debug("请求体解密完成，原始大小: {} bytes, 解密后大小: {} bytes", 
                    encryptedContent.length(), decryptedBytes.length);
            
            return new ByteArrayInputStream(decryptedBytes);
            
        } catch (Exception e) {
            log.error("请求体解密失败", e);
            throw new IOException("请求体解密失败: " + e.getMessage(), e);
        }
    }

    @Override
    public HttpHeaders getHeaders() {
        return inputMessage.getHeaders();
    }

    /**
     * 读取输入流内容
     */
    private String readInputStream(InputStream inputStream, String charset) throws IOException {
        try {
            byte[] buffer = new byte[8192];
            StringBuilder content = new StringBuilder();
            int bytesRead;
            
            while ((bytesRead = inputStream.read(buffer)) != -1) {
                content.append(new String(buffer, 0, bytesRead, charset));
            }
            
            return content.toString();
        } finally {
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    log.warn("关闭输入流失败", e);
                }
            }
        }
    }
}
